package com.fy.qu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fy.core.consts.QuAnswerConstant;
import com.fy.core.consts.QuTypeConstant;
import com.fy.core.context.AuthContext;
import com.fy.core.dto.PageDto;
import com.fy.core.enums.ApiErrorEnum;
import com.fy.core.exception.ServiceException;
import com.fy.core.vo.ApiRest;
import com.fy.core.vo.PageResult;
import com.fy.qu.dto.QuAddDto;
import com.fy.qu.dto.QuSearchDto;
import com.fy.qu.entity.Qu;
import com.fy.qu.entity.QuAnswer;
import com.fy.qu.entity.QuRepo;
import com.fy.qu.mapper.QuAnswerMapper;
import com.fy.qu.mapper.QuMapper;
import com.fy.qu.mapper.QuRepoMapper;
import com.fy.qu.service.QuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.repo.mapper.RepoMapper;
import com.fy.sys.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 问题题目 服务实现类
 * </p>
 *
 * @author hxd
 * @since 2023-06-13
 */
@Service
@Slf4j
public class QuServiceImpl extends ServiceImpl<QuMapper, Qu> implements QuService {
    @Autowired
    private QuRepoMapper quRepoMapper;
    @Autowired
    private QuAnswerMapper quAnswerMapper;
    @Autowired
    private RepoMapper repoMapper;
    @Override
    public PageResult<Qu> findPage(PageDto<QuSearchDto> pageDto) {
        //获取用户信息
        User user = AuthContext.getUser();
        System.out.println("user = " + user);

        //1：设置分页
        IPage<Qu> page = new Page<>(pageDto.getNow(), pageDto.getSize());
        IPage<Qu> pageInfo = this.baseMapper.findPage(page, pageDto.getWhere());

        //3：获取分页信息
        PageResult<Qu> pageResult = new PageResult<>();
        pageResult.setPages(pageInfo.getPages());

        pageResult.setList(pageInfo.getRecords());
        pageResult.setTotal(pageInfo.getTotal());

        return pageResult;
    }

    @Override
    @Transactional
    public ApiRest save(QuAddDto quAddDto) {
        /*1.参数校验*/
        checkData(quAddDto);
        /*2.save qu*/
        Qu qu=new Qu();
        qu.setId(IdWorker.getIdStr());
        qu.setCreateTime(new Date());
        qu.setUpdateTime(new Date());

        BeanUtil.copyProperties(quAddDto,qu,true);
        this.baseMapper.insert(qu);

        /*3.save qu_repo*/
        String[] repoIds = quAddDto.getRepoIds();
        List<QuRepo> quRepoList = Arrays.asList(repoIds).stream().map(repoId -> {
            QuRepo quRepo = new QuRepo();
            quRepo.setId(IdWorker.getIdStr());
            quRepo.setRepoId(repoId);
            quRepo.setQuId(qu.getId());
            quRepo.setQuType(qu.getQuType());

            return quRepo;
        }).collect(Collectors.toList());

        quRepoList.forEach(item->{
            quRepoMapper.insert(item);
        });
        /*4.save qu_answer*/
        List<QuAnswer> answerList=quAddDto.getAnswerList();
        answerList.forEach(item->{
            item.setId(IdWorker.getIdStr());
            item.setQuId(qu.getId());
            quAnswerMapper.insert(item);
        });

        /*5.update repo*/
        for (String repoId : quAddDto.getRepoIds()) {
            repoMapper.updateCountByRepoId(repoId);
        }
        log.info("{}题目录入成功",new Date());
        return ApiRest.success("题目录入成功");
    }

    @Override
    public ApiRest findByQuId(String quId) {
        QuAddDto quAddDto = new QuAddDto();
        Qu qu = this.baseMapper.selectById(quId);
        BeanUtil.copyProperties(qu,quAddDto,true);

        QueryWrapper<QuAnswer> quAnswerQueryWrapper=new QueryWrapper<>();
        quAnswerQueryWrapper.lambda().eq(QuAnswer::getQuId,quId);
        List<QuAnswer> answerList = quAnswerMapper.selectList(quAnswerQueryWrapper);
        quAddDto.setAnswerList(answerList);

        QueryWrapper<QuRepo> quRepoQueryWrapper=new QueryWrapper<>();
        quRepoQueryWrapper.lambda().eq(QuRepo::getQuId,quId);
        List<QuRepo> quRepos = quRepoMapper.selectList(quRepoQueryWrapper);
        List<String> repoList=new ArrayList<>();
        for (QuRepo quRepo : quRepos) {
            repoList.add(quRepo.getRepoId());
        }
        String[] repoIds = repoList.stream().toArray(String[]::new);
        quAddDto.setRepoIds(repoIds);
        return ApiRest.success(quAddDto);
    }

    /**
     * 参数校验
     * @param quAddDto
     */
    private void checkData(QuAddDto quAddDto) {
        if (quAddDto==null){
            throw new ServiceException(ApiErrorEnum.PARAM_SHOULD_NOT_NULL);
        }

        if (StringUtils.isEmpty(quAddDto.getContent())) {
            throw new ServiceException(ApiErrorEnum.QU_CONTENT_IS_NULL);
        }


        if (CollectionUtils.isEmpty(Arrays.asList(quAddDto.getRepoIds()))) {
            throw new ServiceException(ApiErrorEnum.QU_REPO_ATLEAST_ONE);
        }

        List<QuAnswer> answers = quAddDto.getAnswerList();


        if (quAddDto.getQuType() != QuTypeConstant.JDT && CollectionUtils.isEmpty(answers)) {
            throw new ServiceException(ApiErrorEnum.QU_HAS_ANSWER);
        }


        int trueCount = 0;
        for (QuAnswer a : answers) {

            if (StringUtils.isEmpty(a.getContent())) {
                throw new ServiceException(ApiErrorEnum.QU_ANSWER_CONTEXT_IS_NULL);
            }

            if (a.getIsRight() == QuAnswerConstant.RIGHT) {
                trueCount += 1;
            }
        }

        if (trueCount == 0) {
            throw new ServiceException(ApiErrorEnum.QU_ANSWER_HAS_ONE);
        }


        //单选题
        if (quAddDto.getQuType() ==  QuTypeConstant.RADIO  && trueCount > 1) {
            throw new ServiceException(ApiErrorEnum.QU_RADIO_ANSWER_HAS_ONE);
        }
    }
}
